<?php

namespace App\Utils;

use Illuminate\Support\Facades\Redis;
use Exception;
use Illuminate\Support\Facades\Log;

class RedisUtil
{
    /**
     * 设置 Redis 存储
     * @param string $key 键名
     * @param mixed $value 值
     * @param int $ex 过期时间（秒）
     * @return bool
     */
    public static function setData($key, $value, $ex = 3600)
    {
        try {
            $serializedValue = is_array($value) || is_object($value) 
                ? json_encode($value, JSON_UNESCAPED_UNICODE) 
                : $value;
            
            if ($ex > 0) {
                Redis::setex($key, $ex, $serializedValue);
            } else {
                Redis::set($key, $serializedValue);
            }
            
            return true;
        } catch (Exception $e) {
            Log::error('Redis setData error: ' . $e->getMessage(), [
                'key' => $key,
                'exception' => $e
            ]);
            return false;
        }
    }

    /**
     * 获取 Redis 信息
     * @param string $key 键名
     * @return mixed
     */
    public static function getData($key)
    {
        try {
            $value = Redis::get($key);
            
            if ($value === null) {
                return null;
            }
            
            // 尝试解析 JSON
            $decoded = json_decode($value, true);
            if (json_last_error() === JSON_ERROR_NONE) {
                return $decoded;
            }
            
            return $value;
        } catch (Exception $e) {
            Log::error('Redis getData error: ' . $e->getMessage(), [
                'key' => $key,
                'exception' => $e
            ]);
            return null;
        }
    }

    /**
     * 移除 Redis 信息
     * @param string|array $key 键名
     * @return bool
     */
    public static function removeData($key)
    {
        try {
            return Redis::del($key) > 0;
        } catch (Exception $e) {
            Log::error('Redis removeData error: ' . $e->getMessage(), [
                'key' => $key,
                'exception' => $e
            ]);
            return false;
        }
    }

    /**
     * 检查键是否存在
     * @param string $key 键名
     * @return bool
     */
    public static function exists($key)
    {
        try {
            return Redis::exists($key);
        } catch (Exception $e) {
            Log::error('Redis exists error: ' . $e->getMessage(), [
                'key' => $key,
                'exception' => $e
            ]);
            return false;
        }
    }

    /**
     * 设置哈希表字段
     * @param string $key 键名
     * @param string $field 字段名
     * @param mixed $value 值
     * @return bool
     */
    public static function hset($key, $field, $value)
    {
        try {
            $serializedValue = is_array($value) || is_object($value) 
                ? json_encode($value, JSON_UNESCAPED_UNICODE) 
                : $value;
            
            return Redis::hset($key, $field, $serializedValue);
        } catch (Exception $e) {
            Log::error('Redis hset error: ' . $e->getMessage());
            return false;
        }
    }

    /**
     * 获取哈希表字段
     * @param string $key 键名
     * @param string $field 字段名
     * @return mixed
     */
    public static function hget($key, $field)
    {
        try {
            $value = Redis::hget($key, $field);
            
            if ($value === null) {
                return null;
            }
            
            $decoded = json_decode($value, true);
            if (json_last_error() === JSON_ERROR_NONE) {
                return $decoded;
            }
            
            return $value;
        } catch (Exception $e) {
            Log::error('Redis hget error: ' . $e->getMessage());
            return null;
        }
    }

    // 在 RedisUtil 类中添加以下方法

    /**
     * 查找匹配模式的键
     * @param string $pattern 模式
     * @return array
     */
    public static function keys($pattern)
    {
        try {
            return Redis::keys($pattern);
        } catch (Exception $e) {
            Log::error('Redis keys error: ' . $e->getMessage());
            return [];
        }
    }

    /**
     * 获取黑名单IP数量
     * @return int
     */
    public static function getBlacklistCount()
    {
        try {
            $keys = Redis::keys('ip:blacklist:*');
            return count($keys);
        } catch (Exception $e) {
            Log::error('Redis getBlacklistCount error: ' . $e->getMessage());
            return 0;
        }
    }
}
